package com.yupi.springbootinit.statemachine.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yupi.springbootinit.statemachine.core.*;
import com.yupi.springbootinit.statemachine.permission.PermissionManager;
import com.yupi.springbootinit.statemachine.processor.*;
import com.yupi.springbootinit.statemachine.rule.RuleEngine;
import com.yupi.springbootinit.statemachine.rule.RuleValidationResult;
import com.yupi.springbootinit.statemachine.service.StateMachineService;
import com.yupi.springbootinit.statemachine.service.StateTransitionRecordService;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 状态机服务实现类
 * 集成所有状态处理器，提供完整的状态转换功能
 */
@Slf4j
@Service
public class StateMachineServiceImpl implements StateMachineService {
    
    @Resource
    private StateMachine stateMachine;
    
    @Resource
    private ObjectMapper objectMapper;
    
    @Resource
    private PermissionManager permissionManager;
    
    @Resource
    private RuleEngine ruleEngine;
    
    @Resource
    private ApplicationEventPublisher eventPublisher;

    @Resource
    private StateTransitionRecordService stateTransitionRecordService;
    
    // 状态处理器映射
    private final Map<String, StateProcessor> stateProcessors = new ConcurrentHashMap<>();
    
    @Resource
    private OrderStateProcessor orderStateProcessor;
    
    @Resource
    private ProcessInstanceStateProcessor processInstanceStateProcessor;
    
    @Resource
    private ProcessSheetStateProcessor processSheetStateProcessor;
    
    @Resource
    private ProductionScheduleStateProcessor productionScheduleStateProcessor;
    
    @Resource
    private QualityInspectionStateProcessor qualityInspectionStateProcessor;
    
    /**
     * 初始化状态处理器映射
     */
    @PostConstruct
    public void initStateProcessors() {
        stateProcessors.put("ORDER", orderStateProcessor);
        stateProcessors.put("PROCESS_INSTANCE", processInstanceStateProcessor);
        stateProcessors.put("PROCESS_SHEET", processSheetStateProcessor);
        stateProcessors.put("PRODUCTION_SCHEDULE", productionScheduleStateProcessor);
        stateProcessors.put("QUALITY_INSPECTION", qualityInspectionStateProcessor);
        
        log.info("状态处理器初始化完成，注册处理器数量: {}", stateProcessors.size());
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public TransitionResult executeTransition(StateContext context) {
        long startTime = System.currentTimeMillis();
        
        try {
            // 1. 参数验证
            if (!validateContext(context)) {
                return TransitionResult.failure("INVALID_CONTEXT", "状态上下文参数无效", 
                        context.getCurrentState(), context.getEvent());
            }
            
            // 2. 权限验证
            if (!validatePermission(context)) {
                return TransitionResult.failure("PERMISSION_DENIED", "权限不足，无法执行状态转换", 
                        context.getCurrentState(), context.getEvent());
            }
            
            // 3. 业务规则验证
            RuleValidationResult ruleResult = validateBusinessRules(context);
            if (!ruleResult.isValid()) {
                return TransitionResult.failure("RULE_VALIDATION_FAILED", ruleResult.getErrorMessage(), 
                        context.getCurrentState(), context.getEvent());
            }
            
            // 4. 执行核心状态转换（处理器 before/after/onError 由引擎统一执行）
            TransitionResult result = stateMachine.transition(context);
            
            if (result.isSuccess()) {
                // 5. 发布状态变更事件
                publishStateChangeEvent(context, result);
                
                // 6. 保存转换记录
                StateTransitionRecord record = buildTransitionRecord(context, result);
                saveTransitionRecord(record);
                
                log.info("状态转换成功: 实体[{}:{}] {} -> {}, 耗时: {}ms", 
                        context.getEntityType(), context.getEntityId(),
                        context.getCurrentState().getCode(), 
                        context.getTargetState().getCode(),
                        result.getDuration());
            } else {
                log.error("状态转换失败: 实体[{}:{}] {} -> {}, 原因: {}", 
                        context.getEntityType(), context.getEntityId(),
                        context.getCurrentState().getCode(), 
                        context.getTargetState().getCode(),
                        result.getErrorMessage());
            }
            
            // 设置总耗时
            long totalDuration = System.currentTimeMillis() - startTime;
            result.setDuration(totalDuration);
            
            // 性能监控
            if (totalDuration > 1000) {
                log.warn("状态转换耗时过长: {}ms, 实体[{}:{}] {} -> {}", 
                    totalDuration,
                    context.getEntityType(), context.getEntityId(),
                    context.getCurrentState().getCode(), 
                    context.getTargetState().getCode());
            }
            
            return result;
            
        } catch (Exception e) {
            long totalDuration = System.currentTimeMillis() - startTime;
            log.error("状态转换异常: 实体[{}:{}] {} -> {}, 耗时: {}ms", 
                    context.getEntityType(), context.getEntityId(),
                    context.getCurrentState().getCode(), 
                    context.getTargetState().getCode(),
                    totalDuration, e);
            
            return TransitionResult.failure("SYSTEM_ERROR", "系统异常: " + e.getMessage(), 
                    context.getCurrentState(), context.getEvent());
        }
    }
    
    @Override
    public boolean canTransition(String stateType, String fromState, String toState) {
        List<String> allowedStates = stateMachine.getTransitionRules(stateType).get(fromState);
        return allowedStates != null && allowedStates.contains(toState);
    }
    
    @Override
    public List<String> getAvailableTransitions(String stateType, String currentState) {
        return stateMachine.getTransitionRules(stateType).getOrDefault(currentState, new ArrayList<>());
    }
    
    @Override
    public void saveTransitionRecord(StateTransitionRecord record) {
        try {
            record.setCreateTime(new Date());
            // 实际入库
            if (stateTransitionRecordService != null) {
                stateTransitionRecordService.save(record);
            } else {
                log.warn("StateTransitionRecordService 未注入，记录未落库");
            }
            log.debug("保存状态转换记录: 实体[{}:{}] {} -> {}", 
                record.getEntityType(), record.getEntityId(),
                record.getFromStateCode(), record.getToStateCode());
        } catch (Exception e) {
            log.error("保存状态转换记录失败", e);
            // 不抛出异常，避免影响主业务流程
        }
    }
    
    @Override
    public List<StateTransitionRecord> getTransitionHistory(String entityType, Long entityId) {
        try {
            if (stateTransitionRecordService != null) {
                return stateTransitionRecordService.getEntityTransitionHistory(entityType, entityId);
            }
            log.warn("StateTransitionRecordService 未注入，返回空列表");
            return new ArrayList<>();
        } catch (Exception e) {
            log.error("查询状态转换历史异常", e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 验证状态上下文参数
     */
    private boolean validateContext(StateContext context) {
        return StateMachineServiceImplHelper.validateContext(context);
    }
    
    /**
     * 验证权限
     */
    private boolean validatePermission(StateContext context) {
        return StateMachineServiceImplHelper.validatePermission(context, permissionManager);
    }
    
    /**
     * 验证业务规则
     */
    private RuleValidationResult validateBusinessRules(StateContext context) {
        return StateMachineServiceImplHelper.validateBusinessRules(context, ruleEngine);
    }
    
    /**
     * 获取状态处理器
     */
    private StateProcessor getStateProcessor(String entityType) {
        return StateMachineServiceImplHelper.getStateProcessor(entityType, stateProcessors);
    }
    
    /**
     * 发布状态变更事件
     */
    private void publishStateChangeEvent(StateContext context, TransitionResult result) {
        StateMachineServiceImplHelper.publishStateChangeEvent(context, result, eventPublisher);
    }
    
    /**
     * 构建状态转换记录
     */
    private StateTransitionRecord buildTransitionRecord(StateContext context, TransitionResult result) {
        StateTransitionRecord record = new StateTransitionRecord();
        
        record.setEntityId(context.getEntityId());
        record.setEntityType(context.getEntityType());
        record.setFromStateCode(context.getCurrentState().getCode());
        record.setFromStateDesc(context.getCurrentState().getDescription());
        
        if (context.getTargetState() != null) {
            record.setToStateCode(context.getTargetState().getCode());
            record.setToStateDesc(context.getTargetState().getDescription());
        }
        
        if (context.getEvent() != null) {
            record.setEventCode(context.getEvent().getCode());
            record.setEventDesc(context.getEvent().getDescription());
        }
        
        record.setOperatorId(context.getOperatorId());
        record.setOperatorName(context.getOperatorName());
        record.setSuccess(result.isSuccess());
        record.setErrorCode(result.getErrorCode());
        record.setErrorMessage(result.getErrorMessage());
        record.setDuration(result.getDuration());
        record.setRemark(context.getRemark());
        
        // 序列化扩展参数
        if (!context.getParameters().isEmpty()) {
            try {
                record.setParameters(objectMapper.writeValueAsString(context.getParameters()));
            } catch (JsonProcessingException e) {
                log.warn("序列化扩展参数失败", e);
            }
        }
        
        return record;
    }
}